package com.iss.card.view.store;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Intent;
import android.location.Location;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnTouchListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;

import com.iss.card.R;
import com.iss.card.common.ApplicationManager;
import com.iss.card.common.CommonValue;
import com.iss.card.common.FunctionUtil;
import com.iss.card.common.IBackKeyListener;
import com.iss.card.common.MarkProductManager;
import com.iss.card.mapv2.GoogleMapView;
import com.iss.card.mapv2.MyLocationManager;
import com.iss.card.model.ProductDetailInfo;
import com.iss.card.model.StoreAddressInfo;
import com.iss.card.model.StoreDetailInfo;
import com.iss.card.view.model.ResponseBean;
import com.iss.card.webservice.WebServiceAsyncService;
import com.iss.card.webservice.WebServiceAsyncService.Operation;
import com.iss.card.webservice.WebServiceAsyncService.PostExecute;
import com.iss.card.webservice.WebServiceAsyncServiceHelper;
import com.iss.card.webservice.WebServiceManager.WebServiceRegistrationParameter;
import com.iss.card.webservice.WebServiceManager.WebServiceUrlPortManager;
import com.iss.card.webservice.WebServiceUtils;

/**
 * store detail page. it include following functionalities: 1. product list
 * show. 2. go to see in map view. 3. mark or unmark product.
 * 
 * @author dtdh
 * 
 */
public class StoreDetailView implements OnClickListener, IBackKeyListener, OnTouchListener {
	private final String TAG = this.getClass().getSimpleName();
	private Activity mContext;
	private GalleryOverride mGallery;
	/** mark button. it is toggle button. */
	private ImageView mBtCollect;
	/** it is used to display store name in head section. */
	private TextView mTitle;
	/** it is used to save detail information for current store. */
	private StoreDetailInfo mStoreDetailInfo = new StoreDetailInfo();
	/** it is used to save product list for current store. */
	private List<ProductDetailInfo> mProductList = new ArrayList<ProductDetailInfo>();
	/** product id for which will be displayed as the default one. */
	private int mDefaultProductID;
	/** product index in product list which is selected now. */
	private int mCurrentSelectedProductIndex;
	/** adaptor for product list. */
	private ProductListAdapter mAdapter;

	public StoreDetailView(Activity context, FrameLayout layout,
			String storeId, int defaultProductId) {
		this.mContext = context;
		mStoreDetailInfo.setStoreId(storeId);
		mDefaultProductID = defaultProductId;
		mGallery = (GalleryOverride) layout
				.findViewById(R.id.gallery_shops_content_view);
		mGallery.setSpacing(0);
		mAdapter = new ProductListAdapter(mContext, mGallery);
		mGallery.setAdapter(mAdapter);
		mGallery.setOnItemSelectedListener(new OnItemSelectedListener() {

			@Override
			public void onItemSelected(AdapterView<?> parent, View view,
					int position, long id) {
				mCurrentSelectedProductIndex = position;
				updateMarkIcon(getCurrentSelectedProductInfo());
			}

			@Override
			public void onNothingSelected(AdapterView<?> parent) {

			}
		});

		// title name.
		mTitle = (TextView) layout.findViewById(R.id.job_name_val);
		mTitle.setText("");

		// return button.
		Button btCancel = (Button) layout.findViewById(R.id.return_button);
		btCancel.setVisibility(View.VISIBLE);
		btCancel.setBackgroundResource(R.drawable.return_selector);
		btCancel.setOnClickListener(this);

		// button of go to see.
		ImageButton btGoToSee = (ImageButton) layout.findViewById(R.id.job_button);
		btGoToSee.setOnClickListener(this);
		btGoToSee.setVisibility(View.VISIBLE);
		btGoToSee.setBackgroundResource(R.drawable.button_goto_see_normal);

		// button of mark product.
		mBtCollect = (ImageView) layout
				.findViewById(R.id.iv_store_detail_collect);
		mBtCollect.setOnClickListener(this);
		mBtCollect.setEnabled(false);
	}

	/**
	 * get store detail info from server.
	 */
	protected void getStoreDetailInfo() {
		Log.d(TAG,
				"getStoreDetailInfo storeID = " + mStoreDetailInfo.getStoreId());
		getStoreBasicDetailInfo(mStoreDetailInfo.getStoreId());
		downLoadProductInfo(mStoreDetailInfo.getStoreId(),
				FunctionUtil.getCurrentLoginUserMobile());
	}

	private void getStoreBasicDetailInfo(String storeId) {
		Log.d(TAG, "getStoreBasicDetailInfo: storeId=" + storeId);
		WebServiceAsyncService wService = new WebServiceAsyncService();
		wService.setParameterToAsyncService(
				mContext,
				wService.getNextToken(),
				Operation.OP_SERVICE_ARG_GET_STORE_INFO_BY_ID,
				WebServiceRegistrationParameter.PARAMETERS_GET_STORE_INFO_BY_ID,
				new String[] { storeId },
				WebServiceUrlPortManager.ACTION_URL_PORT_STORE_DETAIL_INFO_BY_ID,
				this, WebServiceAsyncServiceHelper.TYPE_HTTP_GET_INSTREAM);
		wService.setPostExecute(new PostExecute() {

			@Override
			public void onAsyncServiceComplete(int token, Object result,
					int index) {
				// TODO error check.
				ResponseBean response = WebServiceUtils
						.getObjectResultToBaseInfo(result,
								StoreDetailInfo.class);
				if (response == null) {
					Log.e(TAG,
							"response for "
									+ WebServiceUrlPortManager.ACTION_URL_PORT_STORE_DETAIL_INFO_BY_ID
									+ " is null.");
					return;
				}

				if (response.getReturnList().size() == 0) {
					Log.e(TAG,
							"there is no result for "
									+ WebServiceUrlPortManager.ACTION_URL_PORT_STORE_DETAIL_INFO_BY_ID);
					return;
				}
				StoreDetailInfo info = (StoreDetailInfo) response
						.getReturnList().get(0);
				mStoreDetailInfo.setStoreAddress(info.getStoreAddress());
				mStoreDetailInfo.setStoreLatitude(info.getStoreLatitude());
				mStoreDetailInfo.setStoreLongitude(info.getStoreLongitude());
				mStoreDetailInfo.setStoreMobile(info.getStoreMobile());
				mStoreDetailInfo.setStoreName(info.getStoreName());
				mStoreDetailInfo.setStoreOwnerID(info.getStoreOwnerID());
				mStoreDetailInfo.setStoreOwnerName(info.getStoreOwnerName());
				mTitle.setText(mStoreDetailInfo.getStoreName());
			}
		});
	}

	/**
	 * download info.
	 */
	private void downLoadProductInfo(String storeID, String mobile) {
		Log.d(TAG, "downLoadProductInfo: storeID = " + storeID + "; mobile = "
				+ mobile);
		WebServiceAsyncService wService = new WebServiceAsyncService();
		wService.setParameterToAsyncService(mContext, wService.getNextToken(),
				Operation.OP_SERVICE_ARG_PRODUCT_INFO,
				WebServiceRegistrationParameter.PRODUCT_INFO_PARAMETER,
				new String[] { storeID, mobile },
				WebServiceUrlPortManager.ACTION_URL_PORT_PRODUCT_INFO, this,
				WebServiceAsyncServiceHelper.TYPE_HTTP_GET_INSTREAM);

		wService.setPostExecute(new PostExecute() {
			@SuppressWarnings("unchecked")
			@Override
			public void onAsyncServiceComplete(int token, Object result,
					int index) {
				// TODO error check.
				ResponseBean response = WebServiceUtils
						.getObjectResultToBaseInfo(result,
								ProductDetailInfo.class);
				mProductList = (ArrayList<ProductDetailInfo>) response
						.getReturnList();
				if (mProductList.size() == 0) {
					Toast.makeText(mContext, R.string.no_product_data_in_store,
							Toast.LENGTH_SHORT).show();
					return;
				}
				addStoreIdIntoProduct(mProductList);
				debugPrint(mProductList);
				mBtCollect.setEnabled(true);
				mCurrentSelectedProductIndex = getDefaultProductIndex();
				Log.d(TAG, "current selected index = "
						+ mCurrentSelectedProductIndex);
				updateMarkIcon(getCurrentSelectedProductInfo());

				// notify to refresh contents.
				mAdapter.setContents(mProductList);
				// display the default product.
				mGallery.setSelection(mCurrentSelectedProductIndex);
				mAdapter.notifyDataSetChanged();
			}
		});
	}

	/**
	 * add store id into each product.
	 * 
	 * @param list
	 *            product list.
	 */
	private void addStoreIdIntoProduct(List<ProductDetailInfo> list) {
		final String storeId = mStoreDetailInfo.getStoreId();
		Log.d(TAG, "addStoreIdIntoProduct: storeId=" + storeId);
		for (ProductDetailInfo info : mProductList) {
			info.setStoreID(storeId);
		}
	}

	@Override
	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.job_button: // button of go to see.
			Log.d(TAG, "Go To see");
			// go to see.
			if (mStoreDetailInfo.getStoreLatitude() == 0) {
				Toast.makeText(mContext, R.string.STR_GET_DATA_IN_PROGRESS,
						Toast.LENGTH_SHORT).show();
				return;
			}

			((FragmentActivity) mContext)
					.startActivity(prepareNavigationData());
			break;

		case R.id.iv_store_detail_collect: // button of collect product.
			ProductDetailInfo info = getCurrentSelectedProductInfo();
			boolean isMark = !isMarkedProduct(info);
			// update current selected product's mark status temporarily.
			updateCurrentSelectedProductInfo(isMark);
			markProduct(info, isMark);
			break;

		case R.id.return_button:
			mContext.finish();
			break;

		default:
			break;
		}
	}

	/**
	 * prepare data for navigation.
	 * 
	 * @return intent with navigation data.
	 */
	private Intent prepareNavigationData() {
		List<StoreAddressInfo> itemList = new ArrayList<StoreAddressInfo>();
		StoreAddressInfo home = new StoreAddressInfo();
		Location current = MyLocationManager.instance().getCurrentPosition();
		home.setStoreLatitude(current.getLatitude());
		home.setStoreLongitude(current.getLongitude());
		home.setStoreName("Current Position");
		home.setStoreAddress("12345678");
		itemList.add(home);

		StoreAddressInfo store = new StoreAddressInfo();
		store.setStoreLatitude(mStoreDetailInfo.getStoreLatitude());
		store.setStoreLongitude(mStoreDetailInfo.getStoreLongitude());
		store.setStoreName(mStoreDetailInfo.getStoreName());
		store.setStoreAddress("ABCDEFGHIDGE");
		itemList.add(store);

		Log.d(TAG,
				"lat=" + store.getStoreLatitude() + ", lon="
						+ store.getStoreLongitude() + ", storeName="
						+ store.getStoreName());
		Intent intent = new Intent(mContext, GoogleMapView.class);
		intent.putExtra(ApplicationManager.KEY_GMAP_MAP_VIEW_MODE,
				CommonValue.EnumGoogleMapviewMode.EGMViewNavigation);
		intent.putExtra(ApplicationManager.KEY_GMAP_POSITION_DATA,
				(Serializable) itemList);
		return intent;
	}

	/**
	 * mark product according to specified status.
	 * 
	 * @param info
	 *            target product.
	 * @param isMark
	 *            mark status.
	 */
	private void markProduct(ProductDetailInfo info, boolean isMark) {
		// TODO show progress bar.
		if (FunctionUtil.isUserLogIn()) {
			requestMarkProduct(FunctionUtil.getCurrentLoginUserMobile(), info,
					isMark);
		} else {
			MarkProductManager.instance().saveMarkedProductInfo(info, isMark);
			responseMarkProduct(0, ApplicationManager.RESPONSE_OK, 0);
		}
	}

	/**
	 * start to send request of mark product to server.
	 * 
	 * @param mobile
	 *            current log in user's mobile
	 * @param info
	 *            product information.
	 * @param isMark
	 *            true means mark product otherwise unmark.
	 */
	private void requestMarkProduct(String mobile, ProductDetailInfo info,
			boolean isMark) {
		WebServiceAsyncService wService = new WebServiceAsyncService();
		wService.setParameterToAsyncService(
				mContext,
				wService.getNextToken(),
				Operation.OP_SERVICE_ARG_COLLECTION,
				WebServiceRegistrationParameter.PRODUCT_COLLECTION,
				new String[] {
						mobile,
						info.getStoreID(),
						String.valueOf(info.getProductID()),
						isMark ? CommonValue.EnumMarkStatus.MARK_PRODUCT
								: CommonValue.EnumMarkStatus.UNMARK_PRODUCT },
				WebServiceUrlPortManager.ACTION_URL_PORT_COLLECTION, this,
				WebServiceAsyncServiceHelper.TYPE_HTTP_GET_INSTREAM);
		wService.setPostExecute(new PostExecute() {

			@Override
			public void onAsyncServiceComplete(int token, Object result,
					int index) {
				ResponseBean response = WebServiceUtils
						.getObjectResultToBaseInfo(result,
								ProductDetailInfo.class);
				String status = response.getStatus();
				String message = response.getMessage();
				Log.d(TAG, "responseMarkProduct: result=" + status + ", reason=" + message);
				responseMarkProduct(token, status, index);
			}
		});
	}

	private void responseMarkProduct(int token, Object result, int index) {
		boolean isMark = isMarkedProduct(getCurrentSelectedProductInfo());
		Log.d(TAG, "responseMarkProduct: result=" + result);
		if (result.equals(ApplicationManager.RESPONSE_OK)) {
			int msgId = R.string.toast_collect_ok;
			int resId = R.drawable.cancel_collection_btn;
			if (!isMark) {
				resId = R.drawable.collection_function_btn;
				msgId = R.string.toast_collect_stop;
			} else {
				resId = R.drawable.cancel_collection_btn;
				msgId = R.string.toast_collect_ok;
			}
			Toast.makeText(mContext, msgId, Toast.LENGTH_SHORT).show();
			mBtCollect.setImageResource(resId);
		} else {
			Toast.makeText(mContext, "Failed to commit", Toast.LENGTH_SHORT)
					.show();
			// recovery it.
			updateCurrentSelectedProductInfo(!isMark);
		}
	}

	/**
	 * update current selected product's mark status.
	 * 
	 * @param isMark
	 *            true means marked otherwise unmarked.
	 */
	private void updateCurrentSelectedProductInfo(boolean isMark) {
		getCurrentSelectedProductInfo().setProductMarked(isMark);
	}

	/**
	 * update mark button background according to mark status.
	 * 
	 * @param info
	 *            product information which will be checked.
	 */
	private void updateMarkIcon(ProductDetailInfo info) {
		int resId = R.drawable.cancel_collection_btn;
		if (isMarkedProduct(info)) {
			resId = R.drawable.cancel_collection_btn;
		} else {
			resId = R.drawable.collection_function_btn;
		}
		mBtCollect.setImageResource(resId);
	}

	/**
	 * check the product is marked or not.
	 * 
	 * @param info
	 *            product information.
	 * @return true means marked otherwise unmarked.
	 */
	private boolean isMarkedProduct(final ProductDetailInfo info) {
		if (FunctionUtil.isUserLogIn()) {
			return info.isProductMarked();
		} else {
			return MarkProductManager.instance().isMarkedProduct(info);
		}
	}

	/**
	 * get default product's index in product list according to product id. if
	 * failed 0 will be return.
	 * 
	 * @return
	 */
	private int getDefaultProductIndex() {
		if (mDefaultProductID == 0) {
			return 0;
		}

		final int num = mProductList.size();
		for (int i = 0; i < num; ++i) {
			if (mProductList.get(i).getProductID() == mDefaultProductID) {
				return i;
			}
		}

		return 0;
	}

	/**
	 * get current selected product's index in product list.
	 * 
	 * @return product index.
	 */
	private ProductDetailInfo getCurrentSelectedProductInfo() {
		return mProductList.get(mCurrentSelectedProductIndex);
	}

	private void debugPrint(List<ProductDetailInfo> list) {
		Log.d(TAG, "====== the following with " + list.size()
				+ " products ==========");
		for (ProductDetailInfo info : list) {
			Log.d(TAG,
					"ProductId=" + info.getProductID() + ", picUrl="
							+ info.getProductPicUrl() + ", picW="
							+ info.getProductPicW() + ", picH="
							+ info.getProductPicH() + ", ProductDeleted="
							+ info.getProductDeleted() + ", marked="
							+ info.isProductMarked() + ", storeId="
							+ info.getStoreID());
		}
		Log.d(TAG, "====== End ==========");
	}

	public void backEvent() {
		if (mAdapter != null) {
			mAdapter.removeThread();
		}
	}

	@Override
	public void cancelUpdate(Object... params) {
		mContext.finish();
	}

	@Override
	public boolean onTouch(View v, MotionEvent event) {
		
		// TODO Auto-generated method stub
		return false;
	}
	
	
}
